use crate::format_parse::FormatParser;
use crate::output_control::{OutputControl, OutputFileWriteMode};
use crate::source_parse::{SourceFileReadMode, SourceParser};
use structopt::StructOpt;

pub mod format_parse;
pub mod output_control;
pub mod source_parse;

#[derive(Debug, StructOpt)]
struct Arguments {
    #[structopt(short = "s", long = "source-file", parse(from_os_str))]
    source_file: std::path::PathBuf,

    #[structopt(short = "m", long = "sfile-mode")]
    sfile_mode: std::string::String,

    #[structopt(short = "f", long = "format-file", parse(from_os_str))]
    format_file: std::path::PathBuf,

    #[structopt(short = "o", long = "output-file", parse(from_os_str))]
    output_file: std::path::PathBuf,

    #[structopt(short = "p", long = "ofile-mode")]
    ofile_mode: std::string::String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args = Arguments::from_args();
    dbg!(&args);
    println!("==================================================");
    let mut ffile = FormatParser::new();
    let _r = ffile.set_fmt_file(&args.format_file);
    let ff_parse_result = ffile.parse();

    let mut rd_mode = SourceFileReadMode::AsBinary;
    match args.sfile_mode.trim() {
        "binary" => rd_mode = SourceFileReadMode::AsBinary,
        "hexstring" => rd_mode = SourceFileReadMode::AsHexString,
        _ => {}
    }

    let mut wr_mode = OutputFileWriteMode::Raw;
    match args.ofile_mode.trim() {
        "raw" => wr_mode = OutputFileWriteMode::Raw,
        "json" => wr_mode = OutputFileWriteMode::Json,
        _ => {}
    }

    match ff_parse_result {
        Ok(okp) => {
            println!("p is {:#?}", okp);

            let mut sfile = SourceParser::new();
            sfile.set_src_file(&args.source_file);

            let mut ofile = OutputControl::new();
            ofile.set_out_file(&args.output_file);

            let out_res = ofile.print_record(&mut sfile, &rd_mode, &mut ffile, &wr_mode, &okp);
        }
        Err(err) => {
            println!("结构体文件解析失败了，错误原因：{}", err);
            return Ok(());
        }
    }

    Ok(())
}
